package com.ecas.code.generator.service.impl;

import com.ecas.code.generator.dao.CodeGeneratorDao;

import com.ecas.code.generator.dto.ParamterDTO;
import com.ecas.code.generator.service.CodeGeneratorService;
import com.ecas.code.generator.service.chain.GeneratorHandler;
import com.ecas.code.generator.service.chain.HandlerFactory;
import com.ecas.code.generator.util.CodeGeneratorFeemarkerUtil;
import com.ecas.code.generator.util.PropertiesUtil;
import com.ecas.code.generator.util.TemplateDataUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipOutputStream;

@Service
public class CodeGeneratorServiceImpl implements CodeGeneratorService {
    private static final Logger log = LoggerFactory.getLogger(CodeGeneratorServiceImpl.class);
    @Autowired
    private CodeGeneratorDao codeGeneratorDao;

    @Override
    public List<Map<String, Object>> queryTable(Map<String, Object> reqParams) {
        return codeGeneratorDao.selectTableInfoList(reqParams);
    }

    @Override
    public Integer countTable(Map<String, Object> reqParams) {
        return codeGeneratorDao.countTable(reqParams);
    }

    @Override
    public byte[] generatorCode(Set<String> tableNames) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
        byte[] resultByte = null;
        try {
            Properties properties = PropertiesUtil.getProperties("config/code-generator.properties");
            for (String tableName : tableNames) {
                Map<String, Object> templateDataMap = getTemplateDataMap(tableName);
                CodeGeneratorFeemarkerUtil.codeGenerator(properties, templateDataMap, zipOutputStream);
            }
            zipOutputStream.flush();
            IOUtils.closeQuietly(zipOutputStream);
            resultByte = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.flush();
        } catch (Exception e) {
            log.error("generatorCode,failed  is Exception:", e);
        } finally {
            IOUtils.closeQuietly(byteArrayOutputStream);
        }
        return resultByte;

    }

    @Override
    public byte[] generatCode(List<ParamterDTO> paramterDTOList) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
        GeneratorHandler handler = HandlerFactory.crreateHandler();
        Properties properties = PropertiesUtil.getProperties("config/code-generator.properties");

        byte[] resultByte = null;
        try {
            for (ParamterDTO paramterDTO : paramterDTOList) {
                Map<String, Object> templateDataMap = getTemplateDataMap(paramterDTO.getTableName());
                handler.setTemplateData(templateDataMap);
                handler.setZipOutputStream(zipOutputStream);
                handler.setProperties(properties);

                handler.handleGenerate(paramterDTO);

            }
            zipOutputStream.flush();
            byteArrayOutputStream.flush();
            resultByte = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return resultByte;
    }


    private Map<String, Object> getTemplateDataMap(String tableName) {
        Map<String, String> tableInfo = codeGeneratorDao.selectTableInfo(tableName);
        List<Map<String, String>> tableColumns = codeGeneratorDao.selectTableColumns(tableName);
        return TemplateDataUtil.getTemplateDataMap(tableInfo, tableColumns);
    }

    public static void main(String[] args) {
        GeneratorHandler handler = HandlerFactory.crreateHandler();
        ParamterDTO paramterDTO = new ParamterDTO();
        handler.handleGenerate(paramterDTO);
    }
}
